package com.ruoyi.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.WechatConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.pojo.WxMpAuthorizationUrl;
import com.ruoyi.service.IWeChatBaseService;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;


/**
 * @author cj
 */
@Service
public class WeChatBaseServiceImpl implements IWeChatBaseService {

    @Autowired
    WechatConfig wechatConfig;

    @Autowired
    RedisCache redisCache;

    @Autowired
    private WxMpService wxMpService;

    String accessTokenKey = UUID.randomUUID().toString();


    /**
     * 1. 获取全局access_token的接口地址（GET） 限200（次/天）
     */
    public static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";

    /**
     * 2. 用于进行网页授权验证的接口URL，通过这个才可以得到opendID等字段信息
     */
    public static final String GET_WEB_AUTH_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";

    /**
     * 3. 获取已关注用户列表
     */
    public static final String GET_ATTENTION_USERLIST_URL = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN";

    /**
     * 4. 获取用户详情
     */
    public static final String GET_USERINFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";


    @Override
    public AjaxResult getAccessToken() {
        String result = storeAccessToken();
        if (StringUtils.isEmpty(result)) {
            return AjaxResult.success("获取 access token 成功");
        } else {
            return AjaxResult.error("获取 access token 失败");
        }
    }


    private String storeAccessToken() {
        String requestUrl = GET_ACCESS_TOKEN_URL.replace("APPID", wechatConfig.getAppId())
                .replace("SECRET", wechatConfig.getSecret());
        String response = HttpUtils.sendGet(requestUrl, null);
        JSONObject jsonObject = JSONObject.parseObject(response);
        String sucessKey = "access_token";
        if (jsonObject.containsKey(sucessKey)) {
            Integer expiresIn = (Integer) jsonObject.get("expires_in");
            redisCache.setCacheObject(accessTokenKey, jsonObject.get("access_token"), expiresIn, TimeUnit.SECONDS);
            return jsonObject.get("access_token").toString();
        } else {
            return null;
        }
    }

    @Override
    public JSONObject getUserInfo(String openId) {
        String accessToken = redisCache.getCacheObject(accessTokenKey);
        if (StringUtils.isEmpty(accessToken)) {
            accessToken = storeAccessToken();
        }
        assert accessToken != null;
        String requestUrl = GET_USERINFO_URL.replace("ACCESS_TOKEN", accessToken)
                .replace("OPENID", openId);
        String response = HttpUtils.sendGet(requestUrl, null);
        JSONObject jsonObject = JSONObject.parseObject(response);
        String sucessKey = "errcode";
        if (jsonObject.containsKey(sucessKey)) {
            String newAccessToken = storeAccessToken();
            requestUrl = GET_USERINFO_URL.replace("ACCESS_TOKEN", newAccessToken)
                    .replace("OPENID", openId);
            response = HttpUtils.sendGet(requestUrl, null);
            jsonObject = JSONObject.parseObject(response);
        }
        return jsonObject;
    }

    @Override
    public AjaxResult webAuth(String code) {
        JSONObject result = getOpenIdByCode(code);
        if (result != null) {
            JSONObject responseJson = new JSONObject();
            responseJson.put("openid", result.get("openid"));
            responseJson.put("scope", result.get("scope"));
            return AjaxResult.success("认证成功", responseJson);
        } else {
            return AjaxResult.error("认证失败");
        }
    }

    private JSONObject getOpenIdByCode(String code) {
        String requestUrl = GET_WEB_AUTH_URL.replace("APPID", wechatConfig.getAppId())
                .replace("SECRET", wechatConfig.getSecret())
                .replace("CODE", code);
        String response = HttpUtils.sendGet(requestUrl, null);
        JSONObject jsonObject = JSONObject.parseObject(response);
        String sucessKey = "access_token";
        if (jsonObject.containsKey(sucessKey)) {
            return jsonObject;
        } else {
            return null;
        }
    }

    @Override
    public String webLogin(String code) {
        JSONObject result = getOpenIdByCode(code);
        String sucessKey = "openid";
        if (result != null && result.containsKey(sucessKey)) {
            return result.get("openid").toString();
        } else {
            return null;
        }
    }

    @Override
    public JSONObject getAttentionUserList(String accessToken) {
        String requestUrl = GET_ATTENTION_USERLIST_URL.replace("ACCESS_TOKEN", accessToken);
        String response = HttpUtils.sendGet(requestUrl, null);
        return JSONObject.parseObject(response);
    }

    @Override
    public String getWebAuthUrl(WxMpAuthorizationUrl wxMpAuthorizationUrl) {
        String response = wxMpService.getOAuth2Service().buildAuthorizationUrl(wxMpAuthorizationUrl.getRedirectUrl(), wxMpAuthorizationUrl.getScope(), wxMpAuthorizationUrl.getState());
        System.out.println(response);
        return response;
    }


}
